package priorityQueue;

// PriorityQueue优先级队列

import java.util.Comparator;
import java.util.PriorityQueue;

class Student implements Comparable<Student> {
    public int age;
    //实现比较器接口，然后再重写compareTo方法
    @Override
    public int compareTo(Student o) {
        return this.age-o.age; // 注意这里的形式！！！
    }
    public Student(int age) {
        this.age = age;
    }
}

class AgeComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age- o2.age;
    }
}

public class Test {
    // 测试5：有时候直接new比较器作为参数传入:然后直接{}重写compare方法
    public static void main(String[] args) {
        // 可以当做匿名内部类
        PriorityQueue<Student> priorityQueue = new PriorityQueue<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.age-o2.age;
            }
        });
        // 上面那段可以简化为：
        PriorityQueue<Student> priorityQueue1 = new PriorityQueue<>((o1,o2)->{return o1.age-o2.age;});
        PriorityQueue<Student> priorityQueue2 = new PriorityQueue<>((o1,o2)->o1.age-o2.age); // 去掉{} 和；
        priorityQueue.offer(new Student(8));
        priorityQueue.offer(new Student(2));

    }

    // 测试4： offer是如何保证小根堆的呢？怎么维护的？
    public static void main4(String[] args) {
        Student student1 = new Student(18);
        Student student2 = new Student(6);

        AgeComparator ageComparator = new AgeComparator();
        PriorityQueue<Student> priorityQueue = new PriorityQueue<>(ageComparator);
        priorityQueue.offer(student1);
        priorityQueue.offer(student2);
    }

    // 测试3：
    public static void main3(String[] args) {
        // 传入比较器
        AgeComparator ageComparator = new AgeComparator();
        PriorityQueue<Student> priorityQueue = new PriorityQueue<>(ageComparator);
        priorityQueue.offer(new Student(1));
        priorityQueue.offer(new Student(2));
    }


    // 不能插入null，会有空指针异常
    // 会自动扩容
    // 插入和删除的时间复杂度都是：log2N

    // 测试2：如果接收的参数是引用类型，一个对象不会错误，读个对象就会出错，因为无法比较大小
    // 所以：offer在添加元素的时候一定要可比较！！（实现Comparable接口）！
    public static void main2(String[] args) {
        PriorityQueue<Student> priorityQueue = new PriorityQueue<>();
        priorityQueue.offer(new Student(3));
        priorityQueue.offer(new Student(5));
        // 使用比较器,在实现比较器接口之后就不会报错！
    }

    // 测试1: 底层是小堆
    public static void main1(String[] args) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
        // 其实是继承于Queue，所以方法类似
        priorityQueue.offer(12);
        priorityQueue.offer(5);
        priorityQueue.offer(82);
        priorityQueue.offer(28);
        System.out.println(priorityQueue.peek()); // 发现输出是5 所以底层默认是小堆！
        // 这里可以直接生成是因为Integer类直接实现了Comparable接口
    }
}
